package com.pets.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.pets.ViewModels.SchoolTimetableViewModels;
import com.pets.ViewModels.StatisticsViewModels;
import com.pets.ViewModels.TodaysCourseViewModels;
import com.pets.mapper.MyCourseMapper;
import com.pets.mapper.UsersMapper;
import com.pets.pojo.CourseManagement;
import com.pets.mapper.CourseManagementMapper;
import com.pets.pojo.FinancialManagement;
import com.pets.pojo.MyCourse;
import com.pets.pojo.Users;
import com.pets.service.ICourseManagementService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pets.utils.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * <p>
 * 课程管理 服务实现类
 * </p>
 *
 * @author 小陳同學
 * @since 2024-05-13
 */
@Service
public class CourseManagementServiceImpl extends ServiceImpl<CourseManagementMapper, CourseManagement> implements ICourseManagementService {

    @Autowired
    private UsersMapper usersMapper;

    @Autowired
    private CourseManagementMapper courseManagementMapper;

    @Autowired
    private MyCourseMapper myCourseMapper;

    /**
     * 创建课程
     * @param courseManagement
     * @return
     */
    @Override
    public Result register(CourseManagement courseManagement) {
        //参数验证
        if(courseManagement == null){
            return Result.fail("未获取到集合");
        }
        if(courseManagement.getCourseData() == null){
            return Result.fail("未设置周几");
        }
        if(courseManagement.getCourseTimeSlot() == null){
            return Result.fail("未设置时间段");
        }
        if(courseManagement.getCourseTypesOf() == null){
            return Result.fail("未设置课程类型");
        }
        if(courseManagement.getUserId() == null){
            return Result.fail("未设置教练人员");
        }
        if(courseManagement.getCourseName() == null){
            return Result.fail("未设置课程名称");
        }
        //未设置消耗会员卡类型默认为0
        if(courseManagement.getConsumptionFrequency() == null){
            courseManagement.setConsumptionFrequency(0);
        }
        //判断课程是否已经添加
        LambdaQueryWrapper<CourseManagement> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CourseManagement::getCourseTimeSlot, courseManagement.getCourseTimeSlot())
                .eq(CourseManagement::getCourseData, courseManagement.getCourseData());
        Long aLong = courseManagementMapper.selectCount(queryWrapper);
        if(aLong!=null&&aLong>0){
            return Result.fail("课程已经存在！");
        }
        return courseManagementMapper.insert(courseManagement) > 0 ? Result.success("成功") : Result.fail("失败");
    }

    /**
     * 删除课程
     * @param id
     * @return
     */
    @Override
    public Result deleteById(Integer id) {
        int rows = courseManagementMapper.deleteById(id);
        return rows > 0 ? Result.success("删除成功") : Result.error("删除失败");
    }

    /**
     * 修改课程
     * @param courseManagement
     * @return
     */
    @Override
    public Result update(CourseManagement courseManagement) {
        int rows = courseManagementMapper.updateById(courseManagement);
        return rows > 0 ? Result.success("修改成功") : Result.error("修改失败");
    }

    /**
     * 查询课程集合
     * @param courseName
     * @param userID
     * @return
     */
    @Override
    public Result list(String courseName, LocalDate beginTime, LocalDate endTime, Integer userID) {
        //返回模型
        List<SchoolTimetableViewModels> schoolTimetableList = new ArrayList<>();

        //判断参数
        if (userID==null){
            return Result.fail("当然登陆人的userID不能为空！");
        }
        if (beginTime==null||endTime==null){
            return Result.fail("开始时间与结束时间不能为空！");
        }
        // 确保开始日期不晚于结束日期
        if (beginTime.isAfter(endTime)) {
            return Result.fail("开始日期不能晚于结束日期！");
        }

        //获取所有课程
        LambdaQueryWrapper<CourseManagement> query = new LambdaQueryWrapper<>();
        query.like(courseName!=null&&!courseName.isEmpty(),CourseManagement::getCourseName,courseName);
        List<CourseManagement> courseManagementList = courseManagementMapper.selectList(query);
        if(courseManagementList==null||courseManagementList.size()==0){
            return Result.fail("未创建课程！");
        }

        //获取当前登陆人所预约的课程
        LambdaQueryWrapper<MyCourse> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(MyCourse::getUserId,userID)
                .ge(MyCourse::getClassTime, beginTime.atStartOfDay())
                .lt(MyCourse::getClassTime, endTime .plusDays(1).atStartOfDay());
        List<MyCourse> financialManagementList = myCourseMapper.selectList(queryWrapper);

        // 计算两个日期之间的天数差（包括两个日期本身）
        long daysBetween = ChronoUnit.DAYS.between(beginTime, endTime) + 1;
        // 使用IntStream生成包含所有日期的列表
        List<LocalDate> datesBetween = IntStream.rangeClosed(0, (int) (daysBetween - 1))
                .mapToObj(beginTime::plusDays)
                .collect(Collectors.toList());

        for (LocalDate localDate : datesBetween) {
            SchoolTimetableViewModels schoolTimetableInfo = new SchoolTimetableViewModels();
            //判断当前时间是星期几
            DayOfWeek dayOfWeek = localDate.getDayOfWeek();
            Integer courseData = null;
            switch (dayOfWeek) {
                case SUNDAY : courseData = 0;schoolTimetableInfo.setCourseDataName("周日");
                    break;
                case MONDAY : courseData = 1;schoolTimetableInfo.setCourseDataName("周一");
                    break;
                case TUESDAY : courseData = 2;schoolTimetableInfo.setCourseDataName("周二");
                    break;
                case WEDNESDAY : courseData = 3;schoolTimetableInfo.setCourseDataName("周三");
                    break;
                case THURSDAY : courseData = 4;schoolTimetableInfo.setCourseDataName("周四");
                    break;
                case FRIDAY : courseData = 5;schoolTimetableInfo.setCourseDataName("周五");
                    break;
                case SATURDAY : courseData = 6;schoolTimetableInfo.setCourseDataName("周六");
                    break;
            };
            if(courseData==null){
                return Result.fail("时间判断错误！");
            }
            schoolTimetableInfo.setCourseData(courseData);
            schoolTimetableInfo.setTimeOfTheDay(localDate);
            //根据星期获取课程集合
            Integer finalCourseData = courseData;
            List<CourseManagement> sortedCourseList = courseManagementList.stream()
                    .filter(a -> a.getCourseData().equals(finalCourseData))
                    .sorted(Comparator.comparing(CourseManagement::getCourseTimeSlot)) // 在流中直接排序
                    .collect(Collectors.toList());
            if (sortedCourseList.size()>0){
                for (CourseManagement courseManagement : sortedCourseList) {
                    TodaysCourseViewModels todaysCourseViewModels = new TodaysCourseViewModels();
                    todaysCourseViewModels.setCourseId(courseManagement.getCourseId());//课程id
                    todaysCourseViewModels.setCourseName(courseManagement.getCourseName());//课程名称
                    if(courseManagement.getUserId()!=null){
                        Users users = usersMapper.selectById(courseManagement.getUserId());
                        if(users!=null){
                            todaysCourseViewModels.setUserId(users.getUserId());//教练id
                            todaysCourseViewModels.setUserName(users.getNickname());//教练名称
                        }
                        //判断任课教师是否等于当前登陆人id
                        if(Objects.equals(courseManagement.getUserId(), userID)){
                            todaysCourseViewModels.setIsTeaching(true);//是否任课
                        }
                    }
                    todaysCourseViewModels.setCourseTimeSlot(courseManagement.getCourseTimeSlot());//课程时间段（枚举）
                    todaysCourseViewModels.setCourseTypesOf(courseManagement.getCourseTypesOf());//课程类型（枚举）
                    todaysCourseViewModels.setConsumptionFrequency(courseManagement.getConsumptionFrequency());//消耗会员次数
                    //获取当前人是否有这个时间课的预约
                    List<MyCourse> myCourseList = financialManagementList.stream()
                            .filter(a -> a.getUserId().equals(userID) &&
                                    a.getCourseId().equals(courseManagement.getCourseId()) &&
                                    a.getClassTime().toLocalDate().equals(localDate))
                            .collect(Collectors.toList());
                    if (myCourseList.size() > 0) {
                        todaysCourseViewModels.setIsReservation(true);
                        todaysCourseViewModels.setMyCourse(myCourseList.get(0).getMyCourse());
                    }
                    // 现在可以直接添加todaysCourseViewModels到列表中，因为无论是否设置了预约，它都应该被添加
                    schoolTimetableInfo.getTodaysCourseList().add(todaysCourseViewModels);
                }
            }
            schoolTimetableList.add(schoolTimetableInfo);
        }
        return Result.success(schoolTimetableList);
    }

}
